import json
import random
import re

from django.contrib.auth import login, logout
from django.shortcuts import render
from django.views import View
from django  import http
from django_redis import get_redis_connection

# Create your views here.
from apps.users.models import User
from apps.verifity.captcha.captcha import captcha
from love_home.settings.dev import logger
from love_home.utils.response_code import RET


class ImageCodeView(View):
    def get(self, request):
        cur = request.GET.get('cur')
        pre = request.GET.get('pre')
        text, image = captcha.generate_captcha()

        redis_conn = get_redis_connection('verify_code')
        redis_conn.setex('img_%s' % cur, 300, text)
        redis_conn.delete('img_%s' % pre)
        # 响应图形验证码: image/jpg
        return http.HttpResponse(image, content_type='image/jpg')

class SMSCodeView(View):
    """短信验证码"""

    def post(self, request):
        # 1.接收参数
        data_dict = json.loads(request.body.decode())
        print(data_dict)
        """
        :param reqeust: 请求对象
        :param mobile: 手机号
        :return: JSON
        """
        # 1. 接收参数
        mobile = data_dict.get('mobile')
        image_code_client = data_dict.get('image_code')
        uuid = data_dict.get('image_code_id')

        # 2. 校验参数
        if not all([image_code_client, uuid]):
            return http.JsonResponse({'errno': 400,
                                      'errmsg': '缺少必传参数'})

        # 3. 创建连接到redis的对象
        redis_conn = get_redis_connection('verify_code')

        # 4. 提取图形验证码
        image_code_server = redis_conn.get('img_%s' % uuid)
        if image_code_server is None:
            # 图形验证码过期或者不存在
            return http.JsonResponse({'errno': 400,
                                      'errmsg': '图形验证码失效'})

        # 5. 删除图形验证码，避免恶意测试图形验证码
        try:
            redis_conn.delete('img_%s' % uuid)
        except Exception as e:
            logger.error(e)

        # 6. 对比图形验证码
        # bytes 转字符串
        image_code_server = image_code_server.decode()
        # 转小写后比较
        if image_code_client.lower() != image_code_server.lower():
            return http.JsonResponse({'errno': 400,
                                      'errmsg': '输入图形验证码有误'})

        # 7. 生成短信验证码：生成6位数验证码
        sms_code = '%06d' % random.randint(0, 999999)
        logger.info(sms_code)

        # 8. 保存短信验证码
        # 短信验证码有效期，单位：300秒
        redis_conn.setex('sms_%s' % mobile,
                         300,
                         sms_code)

        # 9. 发送短信验证码
        from ronglian_sms_sdk import SmsSDK
        #             'account_id'                      'token'          'appid'
        sdk = SmsSDK('8aaf0708697b6beb01699f54fc6317eb','6e5*******1543','8aaf0708697b6beb01699f54fcc517f2')
        #                      短信模板,手机号,  ('短信内容',过期时间),
        sdk.sendMessage('1', mobile, (sms_code,5))
        print('短信验证码:',sms_code)
        # 6. redis中保存短信验证码内容
        try:
            redis_conn.set("SMS_" + mobile, sms_code)
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'errno': 400, 'errmsg': "保存短信验证码失败"})
        # 10. 响应结果
        return http.JsonResponse({'errno': 0,
                                  'errmsg': '发送短信成功'})

class RegisterView(View):

    def post(self, request):
        '''接收参数, 保存到数据库'''
         # 1.接收参数：请求体中的JSON数据 request.body
        json_bytes = request.body # 从请求体中获取原始的JSON数据，bytes类型的
        json_str = json_bytes.decode() # 将bytes类型的JSON数据，转成JSON字符串
        json_dict = json.loads(json_str) # 将JSON字符串，转成python的标准字典
        # json_dict = json.loads(request.body.decode())

        # 提取参数
        password = json_dict.get('password')
        password2 = json_dict.get('password2')
        mobile = json_dict.get('mobile')
        phonecode = json_dict.get('phonecode')

        # 2.校验(整体参数是否为空)
        if not all([password, password2, mobile, phonecode]):
            return http.JsonResponse({'errno':400, 'errmsg':'缺少必传参数!'})

        # 4.password检验
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return http.JsonResponse({'errno': 400, 'errmsg': 'password格式有误!'})

        # 5.password2 和 password
        if password != password2:
            return http.JsonResponse({'errno': 400, 'errmsg': '两次输入不对!'})
        # 6.mobile检验
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.JsonResponse({'errno': 400, 'errmsg': 'mobile格式有误!'})

            # 2. 从redis中获取指定手机号对应的短信验证码的
        redis_conn = get_redis_connection('verify_code')
        try:
            sms_code = redis_conn.get("SMS_" + mobile)
            logger.info(sms_code)
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'errno': 400, 'errmsg': "获取本地验证码失败"})

        if not sms_code:
            return http.JsonResponse({'errno': 400, 'errmsg': "短信验证码过期"})

            # 3. 校验验证码
        if phonecode != sms_code.decode():
            return http.JsonResponse({'errno': 400, 'errmsg': "短信验证码错误"})

        # 8.注册的核心逻辑-保存到数据库 (username password mobile)
        try:
            user =  User.objects.create_user(username=mobile,
                                             password=password,
                                             mobile=mobile)
        except Exception as e:
            return http.JsonResponse({'errno': 400, 'errmsg': '注册失败!'})
        login(request, user)
        # 13.拼接json返回
        return http.JsonResponse({'errno': 0, 'errmsg': '注册成功!'})

class Login(View):
    '''登录'''

    def post(self, request):
        """
        用户登录
        1. 获取参数并对参数进行校验
        2. 从数据库查询出指定的用户
        3. 校验密码
        4. 保存用户登录状态
        5. 返回结果
        """
        # 1. 获取参数和判断是否有值
        data_dict = json.loads(request.body.decode())

        mobile = data_dict.get("mobile")
        password = data_dict.get("password")

        if not all([mobile, password]):
            return http.JsonResponse({'errno': 400, 'errmsg': "参数不全"})

        # 2. 从数据库查询出指定的用户
        try:
            user = User.objects.get(mobile=mobile)
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'errno':400, 'errmsg': "用户不存在"})

        # 3. 校验密码
        if not user.check_password(password):
            return http.JsonResponse({'errno': 400, 'errmsg': "密码错误"})

        # 4. 保存用户登录状态
        login(request, user)

        # 5. 返回结果
        return http.JsonResponse({'errno': 0, 'errmsg': "登录成功"})

class Session(View):
    '''用户状态查询'''

    def get(self, request):
        """
        检测用户是否登录，如果登录，则返回用户的名和用户id
        """
        user = request.user
        if user.is_authenticated:
            data = {'user_id': user.id, 'name': user.username}
            return http.JsonResponse({'errno': RET.OK, 'errmsg': "OK", 'data': data})
        else:
            return http.JsonResponse({'errno': 400, 'errmsg': '用户未登录'})

class Logout(View):
    '''用户退出'''

    def delete(self, request):
        """
        1. 清除session中的对应登录之后保存的信息
        """
        # 清楚session
        logout(request)
        return http.JsonResponse({'errno': RET.OK, 'errmsg': "用户已退出"})